package com.supermap.dialogs;

import com.supermap.data.*;
import com.supermap.dialogs.advance.CJDialog;
import com.supermap.realspace.Scene;
import com.supermap.realspace.TrackingLayer3D;
import com.supermap.realspace.spatialanalyst.Sightline;
import com.supermap.ui.Action3D;
import com.supermap.ui.SceneControl;
import com.supermap.ui.Tracking3DListener;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class SightlineAnalystDialog extends CJDialog {
    private SceneControl sceneControl;

    private Point3D viewPoint3D;
    private ArrayList<Point3D> targetPoint3Ds;
    private int addPointMode;
    private Tracking3DListener tracking3DListener;
    private Sightline sightline;

    public SightlineAnalystDialog(Frame owner, String title, boolean modal, SceneControl sceneControl) {
        super(owner, title, modal, 200, 100, new Object[]{sceneControl});
    }

    @Override
    protected void initializeArgs(Object[] args) {
        this.sceneControl = (SceneControl) args[0];
        targetPoint3Ds = new ArrayList<>();
        addPointMode = 0;
        tracking3DListener = initTracking3DListener();
    }

    @Override
    protected void initializeCore() {
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                super.windowClosed(e);
                if (sceneControl != null) {
                    sceneControl.removeTrackingListener(tracking3DListener);
                    sceneControl.setAction(Action3D.PAN);
                    Scene scene = sceneControl.getScene();
                    scene.getTrackingLayer().clear();
                    targetPoint3Ds.clear();
                    scene.refresh();
                    if (sightline != null) {
                        sightline.clear();
                        sightline.dispose();
                    }
                }
            }
        });
        super.confirmBtn.setText("分析");

        if (sceneControl == null) {
            return;
        }
        sceneControl.addTrackingListener(tracking3DListener);

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(2, 1));
        add(mainPanel, BorderLayout.CENTER);

        JRadioButton addViewPointRBtn = new JRadioButton("添加观察点");
        addViewPointRBtn.addItemListener(e -> {
            JRadioButton item = (JRadioButton) e.getItem();
            if (item.isSelected()) {
                addPointMode = 1;
                sceneControl.setAction(Action3D.CREATE_POINT);
                if (sightline != null) {
                    sightline.clear();
                    TrackingLayer3D trackingLayer = sceneControl.getScene().getTrackingLayer();
                    trackingLayer.clear();
                }
            }
        });
        mainPanel.add(addViewPointRBtn);

        JRadioButton addTargetPointRBtn = new JRadioButton("添加目标点");
        addTargetPointRBtn.addItemListener(e -> {
            JRadioButton item = (JRadioButton) e.getItem();
            if (item.isSelected()) {
                addPointMode = 2;
                sceneControl.setAction(Action3D.CREATE_POINT);
            }
        });
        mainPanel.add(addTargetPointRBtn);

        ButtonGroup buttonGroup = new ButtonGroup();
        buttonGroup.add(addViewPointRBtn);
        buttonGroup.add(addTargetPointRBtn);
    }

    @Override
    protected void doConfirmCore() {
        if (sceneControl == null || viewPoint3D == null || targetPoint3Ds.size() == 0) {
            return;
        }

        sightline = new Sightline(sceneControl.getScene());
        sightline.setViewerPosition(viewPoint3D);
        sightline.setVisibleColor(Color.GREEN);
        sightline.setHiddenColor(Color.RED);
        for (Point3D targetPoint3D : targetPoint3Ds) {
            sightline.addTargetPoint(targetPoint3D);
        }
        sightline.build();
    }

    private Tracking3DListener initTracking3DListener() {
        return tracking3DEvent -> {
            Point3D point3D = new Point3D(tracking3DEvent.getX(), tracking3DEvent.getY(), tracking3DEvent.getZ());
            if (sceneControl.getAction() == Action3D.CREATE_POINT) {
                Scene scene = sceneControl.getScene();
                TrackingLayer3D trackingLayer = scene.getTrackingLayer();
                switch (addPointMode) {
                    case 1:
                        viewPoint3D = point3D;
                        GeoPoint3D viewPoint3D = new GeoPoint3D(point3D);
                        GeoStyle3D viewPointStyle3D = new GeoStyle3D();
                        viewPointStyle3D.setMarkerSize(6);
                        viewPointStyle3D.setMarkerSymbolID(1);
                        viewPointStyle3D.setFillForeColor(Color.GREEN);
                        viewPointStyle3D.setFillBackColor(Color.GREEN);
                        viewPointStyle3D.setFillMode(FillMode3D.LINE_AND_FILL);
                        viewPoint3D.setStyle3D(viewPointStyle3D);

                        GeoText3D viewPointText3D = new GeoText3D();
                        TextPart3D viewText3DPart = new TextPart3D();
                        viewText3DPart.setAnchorPoint(point3D);
                        viewText3DPart.setText("观察点");
                        viewPointText3D.addPart(viewText3DPart);
                        viewPointText3D.setStyle3D(viewPointStyle3D);

                        int viewPoint3DIndex = trackingLayer.indexOf("viewPoint3D");
                        if (viewPoint3DIndex != -1) {
                            trackingLayer.remove(viewPoint3DIndex);
                        }

                        trackingLayer.add(viewPoint3D, "viewPoint3D");
                        trackingLayer.add(viewPointText3D, "viewPoint3D");
                        break;
                    case 2:
                        targetPoint3Ds.add(point3D);
                        GeoPoint3D targetPoint3D = new GeoPoint3D(point3D);
                        GeoStyle3D targetPointStyle3D = new GeoStyle3D();
                        targetPointStyle3D.setMarkerSize(6);
                        targetPointStyle3D.setFillForeColor(Color.RED);
                        targetPointStyle3D.setFillBackColor(Color.RED);
                        targetPointStyle3D.setFillMode(FillMode3D.LINE_AND_FILL);
                        targetPoint3D.setStyle3D(targetPointStyle3D);

                        GeoText3D targetPointText3D = new GeoText3D();
                        TextPart3D targetText3DPart = new TextPart3D();
                        targetText3DPart.setAnchorPoint(point3D);
                        targetText3DPart.setText("目标点" + targetPoint3Ds.size());
                        targetPointText3D.addPart(targetText3DPart);
                        targetPointText3D.setStyle3D(targetPointStyle3D);

                        trackingLayer.add(targetPoint3D, "targetPoint3Ds");
                        trackingLayer.add(targetPointText3D, "targetPoint3Ds");
                        break;
                }
            }
        };
    }
}
